unit dllWorkClass;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, StdCtrls, Controls, Forms,
  Dialogs, mException;

type
  TStrArr = array of String;
  TFloatArr = array of Double;
  THandle = LongInt;

  TGetName = function : String;
  TGetParamsCount = function : Integer;
  TSetParam = procedure(index: Integer; value: Double);
  TGetParamLabel = function(index: Integer): String;
  TCheckParams = function(params: array of Double): Boolean;
  TGetParamsRequirementsText = function : String;

  TDllWorkClass = Class(TObject)
    protected
      dllPath       : String;
      dllHandle     : THandle;

      params        : TFloatArr;
      paramsCount   : Integer;
      paramsLabels  : TStrArr;

      aGetParamsCount : TGetParamsCount;
      aSetParam      : TSetParam;
      aGetName       : TGetName;
      aGetParamLabel : TGetParamLabel;
      aCheckParams   : TCheckParams;
      aGetParamsRequirementsText : TGetParamsRequirementsText;

    public

      constructor Create(dll_path: String);
      destructor  Destroy; override;

      function getName: String;
      function getParamsCount: Integer;
      function getParamLabel(index: Integer): String;
      function checkParams: Boolean;
      function getParamsRequirementsText: String;
      procedure setParam(index: Integer; value: Double);
  end;

implementation

constructor TDllWorkClass.Create(dll_path: String);
var  i: Integer;
begin
  dllPath := dll_path;
  dllHandle := LoadLibrary(PWideChar(WideString(dll_path)));
  if GetLastError = ERROR_DLL_NOT_FOUND then
    raise TMException.Create('Dll not found');
  paramsCount := getParamsCount();
  setLength(params, paramsCount);
  setLength(paramsLabels, paramsCount);
  for i := 0 to paramsCount - 1 do
  begin
      params[i] := 0;
      paramsLabels[i] := self.getParamLabel(i);
  end;
end;

destructor TDllWorkClass.Destroy;
begin
  setLength(params, 0);
end;

function TDllWorkClass.getParamsCount: Integer;
begin
  @self.aGetParamsCount := GetProcAddress(dllHandle, 'getParamsCount');
  if Addr(self.aGetParamsCount) = nil then
    raise TMException.Create('Function getParamsCount not found');
  Result := self.aGetParamsCount;
end;

procedure TDllWorkClass.setParam(index: Integer; value: Double);
begin
  //TODO: validate input params
  params[index] := value;
end;

function TDllWorkClass.checkParams: Boolean;
begin
  @self.aCheckParams := GetProcAddress(DllHandle, 'checkParams');
  if Addr(self.aCheckParams) = nil then
    raise TMException.Create('Function checkParams not found');
  Result := self.aCheckParams(params);
end;

function TDllWorkClass.getParamsRequirementsText: String;
begin
  @self.aGetParamsRequirementsText := GetProcAddress(DllHandle, 'getParamsRequirementsText');
  if Addr(self.aGetParamsRequirementsText) = nil then
    raise TMException.Create('Function fgetParamsRequirementsText not found');
  Result := self.aGetParamsRequirementsText;
end;

function TDllWorkClass.getName;
begin
  @self.aGetName := GetProcAddress(dllHandle, 'getName');
  if Addr(self.aGetName) = nil then
    raise TMException.Create('Function f(x) not found');
  Result := self.aGetName;
end;

function TDllWorkClass.getParamLabel(index: Integer):String;
begin
  @self.aGetParamLabel := GetProcAddress(dllHandle, 'getParamLabel');
  if Addr(self.aGetParamLabel) = nil then
    raise TMException.Create('Function getParamLabel not found');
  Result := self.aGetParamLabel(index);
end;


end.
